﻿using System.Collections.Generic;
using Orchard.ContentManagement;
using Orchard.Localization;
using Orchard.Workflows.Models;
using Orchard.Workflows.Services;

using System.Linq;
using Orchard.Core.Common.Models;
using Orchard.Messaging.Events;
using Orchard.Messaging.Models;
using Orchard.Messaging.Services;
using Orchard.ContentManagement;
using Orchard.Localization;
using Orchard.Security;

using Orchard;
using Orchard.Scripting.CSharp.Services;
using Coevery.OptionSet;
using Coevery.OptionSet.Models;
using Orchard.Core.Title.Models;
using Coevery.Fields.Fields;
using System;
using Coevery.Fields.ViewModels;
using Coevery.Tasacion.Services;



namespace Coevery.Tasacion.Activities {
    public class SearchInfoActivity : Task {
        private readonly IContentManager _contentManager;
        private readonly IOrchardServices _orchardServices;
        //private readonly ICSharpService _csharpService;
        private readonly IWorkContextAccessor _workContextAccessor;
        private readonly Coevery.OptionSet.Services.IOptionSetService _optionSetService;
        private readonly Coevery.Tasacion.Services.ITasacionService _tasacionService;

        public SearchInfoActivity(IContentManager contentManager, IOrchardServices orchardServices,
            IWorkContextAccessor workContextAccessor, 
            Coevery.OptionSet.Services.IOptionSetService optionSetService,
            Coevery.Tasacion.Services.ITasacionService tasacionService/*,ICSharpService csharpService*/)
        {
            _contentManager = contentManager;
            _orchardServices = orchardServices;
            //_csharpService = csharpService;
            _workContextAccessor = workContextAccessor;
            _optionSetService = optionSetService;
            _tasacionService = tasacionService;

        }

        public Localizer T { get; set; }

        public override bool CanExecute(WorkflowContext workflowContext, ActivityContext activityContext) {
            return true;
        }

        public override IEnumerable<LocalizedString> GetPossibleOutcomes(WorkflowContext workflowContext, ActivityContext activityContext) {
            return new[] { T("Success"), T("Error") };
        }

        public override IEnumerable<LocalizedString> Execute(WorkflowContext workflowContext, ActivityContext activityContext) {
 
            ContentItem contentItem = workflowContext.Content.ContentItem;
            
            OptionItemContainerPart contentPart = (OptionItemContainerPart)contentItem.Parts.FirstOrDefault(p => p.PartDefinition.Name.Contains("OptionItemContainerPart"));
            ContentPart viviendaPart = (ContentPart)contentItem.Parts.FirstOrDefault(p => p.PartDefinition.Name.Contains("Vivienda"));
            
            IList<OptionItemContentItem> optionItems = contentPart.OptionItems;
            IEnumerable<ContentField> flds = viviendaPart.Fields;

            string CCAA = GetOptionSetValue(optionItems, "CCAA");
            string Provincia = GetOptionSetValue(optionItems, "Provincia");
            string Municipio = GetOptionSetValue(optionItems, "Municipio");
            string TipoVia = GetOptionSetValue(optionItems, "TipoVia");

            string NombreVia = GetFieldValue(flds, "NombreVia");
            string Numero = GetFieldValue(flds, "Numero");
            string Barrio = GetFieldValue(flds, "Barrio");
            string CodigoPostal = GetFieldValue(flds, "CodigoPostal");

            MapField map = (MapField)viviendaPart.Fields.FirstOrDefault(x => x.Name == "Coordenadas");
            GeographicalPoint point;
            if (map != null && map.Value != null)
            {
                point = map.Value;
            }
            else
            {
                point = _tasacionService.GetCoordinates(CCAA, Provincia, Municipio, CodigoPostal, TipoVia, NombreVia, Numero);
                map.Value = point;
            }

            _tasacionService.GetAndSavePisosCercanos(contentItem, point, GetFieldValue(flds, "Vivienda"));

            _contentManager.Publish(workflowContext.Content.ContentItem);
            yield return T("Success");
        }

        private string GetOptionSetValue (IList<OptionItemContentItem> optionItems, string key)
        {
            OptionItemContentItem ccaaItem = optionItems.FirstOrDefault(x => x.Field == key);
            TitlePart title = _contentManager.Query<Orchard.Core.Title.Models.TitlePart, Orchard.Core.Title.Models.TitlePartRecord>()
                    .Where(x => x.ContentItemRecord.Id == ccaaItem.OptionItemRecord.Id)
                    .Slice(0, 1)
                    .FirstOrDefault();
            string result = title.Title;
            return result;
        }

        private string GetFieldValue(IEnumerable<ContentField> fields, string key)
        {
            ContentField field = fields.FirstOrDefault(x => x.Name == key);
            string result = GetPropertyValue(field, "Value").ToString();
            return result;
        }

        public override string Name {
            get { return "SearchInfo"; }
        }

        public override LocalizedString Category {
            get { return T("Search InmuebleIdealistaOverviews (testigos) when a Vivienda is created"); }
        }

        public override LocalizedString Description {
            get { return T("Search InmuebleIdealistaOverviews."); }
        }

        private static object GetPropertyValue(object obj, string propertyName)
        {
            System.Reflection.PropertyInfo info = obj.GetType().GetProperty(propertyName);
            if (info == null) return null;
            if (info.PropertyType.Name.Contains("GeographicalPoint"))
            {
                return null;
                // TODO Cuando esten seteados las coordenadas geográficas debería devolver un GeographicalPoint
            }
            return info.GetValue(obj, null);
        }

        private void DummyGetAllData (ContentItem contentItem){
        
            OptionItemContainerPart contentPart = (OptionItemContainerPart)contentItem.Parts.FirstOrDefault(p => p.PartDefinition.Name.Contains("OptionItemContainerPart"));
            IList<OptionItemContentItem> optionItems = contentPart.OptionItems;

            foreach (OptionItemContentItem item in optionItems)
            {
                string field = item.Field;
                int optionitem_contentitem_id = item.Id;
                int contentitemrecord_id = item.OptionItemRecord.Id;
                int optionset_id = item.OptionItemRecord.OptionSetId;

                TitlePart title = _contentManager.Query<Orchard.Core.Title.Models.TitlePart, Orchard.Core.Title.Models.TitlePartRecord>()
                    .Where(x => x.ContentItemRecord.Id == contentitemrecord_id)
                    .Slice(0, 1)
                    .FirstOrDefault();

                System.Diagnostics.Debug.WriteLine(title.Title);
            }

            ContentPart viviendaPart = (ContentPart)contentItem.Parts.FirstOrDefault(p => p.PartDefinition.Name.Contains("Vivienda"));
            IEnumerable<ContentField> flds = viviendaPart.Fields;

            foreach (ContentField fld in flds)
            {
                string field = fld.DisplayName;
                object val = GetPropertyValue(fld, "Value");
                if (val != null)
                {
                    System.Diagnostics.Debug.WriteLine(val.ToString());
                }
                
            }
        }
    }
}